﻿using System;
using System.Windows.Forms;
using Client.Controllers;
using Client.Interfaces;
using Global.Interfaces.Server;
using System.IO;

namespace Client
{
    internal partial class ChatWindow : Form, IChatView
    {
        #region Variables
        private IChatController _controller;
        #endregion

        #region Constructors
        internal ChatWindow(IMainController form, string endpoint, string password)
        {
            InitializeComponent();

            InitController(form, endpoint, password, null);
        }

        internal ChatWindow(IMainController form, string endpoint, string password, IBuddy buddy)
        {
            InitializeComponent();

            InitController(form, endpoint, password, buddy);
        }

        private void InitController(IMainController form, string endpoint, string password, IBuddy buddy)
        {
            _controller = new ChatController(form, this, endpoint, password, buddy);
            tbMessage.Enabled = false;
        }
        #endregion

        #region UI events
        private void ChatWindow_Load(object sender, EventArgs e)
        {
            _controller.InitChat();
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            string message = tbMessage.Text;
            _controller.Send(tbMessage.Text);
            tbMessage.Text = string.Empty;
            btnSend.Enabled = false;
            tbMessage.Focus();
        }

        private void tbMessage_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                btnSend_Click(this, null);
            btnSend.Enabled = tbMessage.Text.Length > 0;
        }

        private void tbMessage_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                e.Handled = true;
            }
        }

        private void ChatWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            _controller.Leave();
        }

        private void btnShareFile_Click(object sender, EventArgs e)
        {
            DialogResult dr = fileDialog.ShowDialog();
            if (dr == DialogResult.OK)
                _controller.SendFile(fileDialog.FileName);
        }

        private void tbMessage_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(TreeNode)))
            {
                e.Effect = DragDropEffects.Copy;
            }
            else
                e.Effect = DragDropEffects.None;
        }

        private void tbMessage_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(TreeNode)))
            {
                _controller.NodeDropped(e.Data.GetData(typeof(TreeNode)));
            }
        }
        #endregion

        #region IChatView Members

        public string Log
        {
            get
            {
                string tmp = string.Empty;
                MethodInvoker invoker = delegate { tmp = tbLog.Text; };
                if (!this.IsDisposed)
                    this.Invoke(invoker);
                return tmp;
            }
            set
            {
                MethodInvoker invoker = delegate { tbLog.Text = value; };
                if (!this.IsDisposed)
                    this.Invoke(invoker);
            }
        }

        public void CloseWindow()
        {
            MethodInvoker invoker = delegate
            {
                this.Close();
            };
            if (!this.IsDisposed)
                this.Invoke(invoker);
        }

        public void Alert(string message)
        {
            MessageBox.Show(message);
        }

        public void Ready()
        {
            MethodInvoker invoker = delegate
            {
                tbMessage.Enabled = true;
                tbMessage.Focus();
            };
            if (!this.IsDisposed)
                this.Invoke(invoker);
        }

        public string Title
        {
            get
            {
                string tmp = string.Empty;
                MethodInvoker invoker = delegate
                {
                    tmp = this.Text;
                };
                this.Invoke(invoker);
                return tmp;
            }
            set
            {
                MethodInvoker invoker = delegate
                {
                    this.Text = value;
                };
                this.Invoke(invoker);
            }
        }

        public void FileReceived(Stream fromStream, string username, string filename)
        {
            MethodInvoker invoker = delegate
            {
                if (MessageBox.Show("Want to download file '" + filename + "' from '" + username + "'?", "File request", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
                {
                    SaveFileDialog dialog = new SaveFileDialog();
                    dialog.FileName = filename;
                    DialogResult dr = dialog.ShowDialog();
                    if (dr == DialogResult.OK)
                    {
                        using (Stream toStream = File.Create(dialog.FileName))
                        {
                            BinaryReader br = new BinaryReader(fromStream);
                            BinaryWriter bw = new BinaryWriter(toStream);

                            try
                            {
                                Byte b = br.ReadByte();
                                while (true)
                                {
                                    bw.Write(b);
                                    b = br.ReadByte();
                                }
                            }
                            catch (Exception) { }

                            bw.Flush();
                            bw.Close();
                            br.Close();
                        }
                    }
                }
            };
            this.Invoke(invoker);
        }

        #endregion
    }
}
